package com.wiscamp.ninechapters.problems.application.services;

import com.wiscamp.ninechapters.problems.application.assemblers.SheetAssembler;
import com.wiscamp.ninechapters.problems.application.dto.commands.sheets.SubmitSheetCommand;
import com.wiscamp.ninechapters.problems.application.dto.vo.sheets.SheetVO;
import com.wiscamp.ninechapters.problems.domain.models.sheets.Sheet;
import com.wiscamp.ninechapters.problems.domain.models.sheets.SheetAnswer;
import com.wiscamp.ninechapters.problems.domain.models.sheets.SheetDetail;
import com.wiscamp.ninechapters.problems.domain.repositories.SheetRepository;
import com.wiscamp.ninechapters.problems.domain.repositories.TaskRepository;
import com.wiscamp.ninechapters.problems.domain.services.SheetService;
import com.wiscamp.ninechapters.problems.enums.AnswerTypes;
import com.wiscamp.ninechapters.problems.enums.SheetStatus;
import com.wiscamp.ninechapters.problems.enums.SheetTypes;
import cube.ddd.application.BaseAppService;
import cube.ddd.aspect.HandleServiceException;
import cube.ddd.utils.AppServiceUtils;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.Collection;
import java.util.Objects;

@Service
public class SheetAppService extends BaseAppService {

    private final SheetRepository sheetRepository;

    private final TaskRepository taskRepository;

    private final SheetService sheetService;

    public SheetAppService(SheetRepository sheetRepository, TaskRepository taskRepository, SheetService sheetService) {
        this.sheetRepository = sheetRepository;
        this.taskRepository = taskRepository;
        this.sheetService = sheetService;
    }

    @HandleServiceException
    public SheetVO getSheet(long sheetId) {
        return AppServiceUtils.getById(sheetId, sheetRepository::getSheet,
                SheetAssembler.Instance::toSheetVO);
    }

    @HandleServiceException
    public Collection<SheetVO> getSheetsByUser(@Min(0) long userId) {
        return AppServiceUtils.getListById(userId, sheetRepository::getSheetsByUser,
                SheetAssembler.Instance::toSheetVO);
    }

    @HandleServiceException
    public SheetVO submitSheet(@NotNull SubmitSheetCommand command) {
        command.setOperatorId(getCurrentUserId());
        var sheet = buildSheetByCommand(command);
        var newSheet = sheetService.submitSheet(sheet);
        if (Objects.isNull(newSheet)) return null;
        return SheetAssembler.Instance.toSheetVO(newSheet);
    }

    private Sheet buildSheetByCommand(SubmitSheetCommand command) {
        var sheet = new Sheet();
        sheet.setUserId(command.getUserId());
        sheet.setTaskId(command.getTaskId());
        sheet.setSheetStatusId(SheetStatus.NOT_COMPLETED.getValue());
        sheet.setBeginTime(command.getBeginTime());
        sheet.setEndTime(command.getEndTime());
        sheet.setSheetTypeId(SheetTypes.GENERAL.getValue());

        var task = taskRepository.getTask(command.getTaskId());
        if (Objects.nonNull(task)) sheet.setSetId(task.getSetId());
        for (var detailDto : command.getDetails()) {
            var sheetDetail = new SheetDetail();
            sheetDetail.setQuestionBeginTime(detailDto.getQuestionBeginTime());
            sheetDetail.setQuestionEndTime(detailDto.getQuestionEndTime());
            sheetDetail.setSolutionUrl(detailDto.getSolutionUrl());
            sheetDetail.setQuestionId(detailDto.getQuestionId());
            sheetDetail.setProblemId(detailDto.getProblemId());
            sheet.getDetails().add(sheetDetail);

            if (detailDto.getSheetAnswers().size() <= 0) {
                var sheetAnswer = new SheetAnswer();
                sheetAnswer.setSkipped(true);
                sheetAnswer.setAnswerIndex(1);
                sheetAnswer.setContentText("");
                sheetAnswer.setOptionContentText("");
                sheetDetail.getSheetAnswers().add(sheetAnswer);
            } else {
                for (var sheetAnswerDto : detailDto.getSheetAnswers()) {
                    var sheetAnswer = new SheetAnswer();
                    sheetAnswer.setContentText(sheetAnswerDto.getContentText());
                    sheetAnswer.setSkipped(sheetAnswerDto.isSkipped());
                    //sheetAnswer.setCorrectAnswerTypeId();
                    sheetAnswer.setContentTypeId(sheetAnswerDto.getContentTypeId());
                    sheetAnswer.setAnswerIndex(sheetAnswerDto.getAnswerIndex());

                    var answerType = AnswerTypes.valueOf(sheetAnswerDto.getContentTypeId());
                    if (answerType == AnswerTypes.OPTION || answerType == AnswerTypes.MULTIPLE_OPTION) {
                        sheetAnswer.setOptionContentText(sheetAnswerDto.getContentText());
                    } else {
                        sheetAnswer.setContentText(sheetAnswerDto.getContentText());
                    }

                    if (sheetAnswerDto.isSkipped()) {
                        sheetAnswer.setOptionContentText("");
                        sheetAnswer.setContentText("");
                    }
                    sheetDetail.getSheetAnswers().add(sheetAnswer);
                }
            }

            if (sheetDetail.getQuestionBeginTime() != null && sheetDetail.getQuestionEndTime() != null &&
                    sheetDetail.getAnsweringSeconds() == 0) {
                Duration duration = Duration.between(sheetDetail.getQuestionBeginTime(), sheetDetail.getQuestionEndTime());
                int seconds = (int) duration.toSeconds();
                sheetDetail.setAnsweringSeconds(seconds);
            }
        }
        return sheet;
    }
}
